package org.finesys.common.sms.Service;

import cn.hutool.core.util.RandomUtil;
import cn.hutool.json.JSONUtil;
import com.aliyuncs.CommonRequest;
import com.aliyuncs.CommonResponse;
import com.aliyuncs.DefaultAcsClient;
import com.aliyuncs.IAcsClient;
import com.aliyuncs.exceptions.ClientException;
import com.aliyuncs.http.MethodType;
import com.aliyuncs.profile.DefaultProfile;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.finesys.common.constants.SecurityConstants;
import org.finesys.common.sms.properties.SmsProperties;
import org.springframework.boot.autoconfigure.AutoConfiguration;
import org.springframework.data.redis.core.StringRedisTemplate;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.TimeUnit;

@AutoConfiguration
@RequiredArgsConstructor
@Slf4j
public class SmsService {

    private final SmsProperties smsProperties;
    private final StringRedisTemplate stringRedisTemplate;

    /**
     * 发送短信
     */
    public Boolean sendSmsCode(String phone) {
        //随机生成6位验证码
        String code = RandomUtil.randomNumbers(6);
        //缓存生成的六位验证码
        stringRedisTemplate.opsForValue().set(SecurityConstants.SMS_CODE_PREFIX + phone, code, 10, TimeUnit.MINUTES);
        //创建发送客户端
        IAcsClient client = createClient();
        //创建通用的请求对象
        Map<String, String> params = new HashMap<>();
        // 指定地域名称
        params.put("RegionId", smsProperties.getRegionId());
        // 要给哪个手机号发送短信 指定手机号
        params.put("PhoneNumbers", phone);
        // 您的申请签名
        params.put("SignName", smsProperties.getSignName());
        // 您申请的模板 code
        params.put("TemplateCode", smsProperties.getTemplateCode());
        //模版参数
        Map<String, Object> extParams = new HashMap<>();
        extParams.put("code", code);
        params.put("TemplateParam", JSONUtil.toJsonStr(params));
        //创建通用的请求对象
        CommonRequest commonRequest = createCommonRequest(MethodType.POST, "SendSms", smsProperties.getDomain(), "2017-05-25", params);

        try {
            CommonResponse response = client.getCommonResponse(commonRequest);
            return response.getHttpResponse().isSuccess();
        } catch (ClientException e) {
            log.error("发送短信失败[{}]", e.getErrMsg());
        }
        return Boolean.FALSE;
    }

    /**
     * 创建发送客户端
     */
    private IAcsClient createClient() {
        String regionId = smsProperties.getRegionId();
        String accessKeyId = smsProperties.getAccessKeyId();
        String secret = smsProperties.getAccessKeySecret();
        DefaultProfile profile = DefaultProfile.getProfile(regionId, accessKeyId, secret);
        return new DefaultAcsClient(profile);
    }

    /**
     * 创建通用的请求对象
     */
    private CommonRequest createCommonRequest(MethodType methodType, String sysAction, String domain, String sysVersion, Map<String, String> params) {
        // 创建通用的请求对象
        CommonRequest request = new CommonRequest();
        // 指定请求方式
        request.setSysMethod(methodType);
        // 短信api的请求地址 固定
        request.setDomain(domain);
        // 签名算法版本 固定
        request.setSysVersion(sysVersion);
        // 请求 API 的名称
        request.setSysAction(sysAction);
        //参数
        if (params != null) {
            for (Map.Entry<String, String> entry : params.entrySet()) {
                String key = entry.getKey();
                String value = entry.getValue();
                request.putQueryParameter(key, value);
            }
        }
        return request;
    }
}
